﻿//using System;
//using System.Collections.Generic;
//using System.Linq;
//using System.Text;
//using System.Threading.Tasks;

//namespace ArgusPCLib.Mathematics
//{
//	public struct Fraction : ILinearScalar
//	{
//		public decimal Numerator { get; private set; }
//		public decimal Denominator { get; private set; }

//		public Fraction(decimal num, decimal den)
//			: this(num, den, Math.GCD(num, den)) { }

//		public Fraction(decimal d)
//			:this()
//		{
//			int p = d.GetLengthOfDecimalFraction();
//			this.Numerator = d.ShiftLeft(p);
//			this.Denominator = decimal.One / decimal.One.ShiftRight(p);
//			decimal gcd = Math.GCD(this.Numerator, this.Denominator);
//			this.Numerator /= gcd;
//			this.Denominator /= gcd;
//		}

//		private Fraction(decimal num, decimal den, decimal gcd)
//			:this()
//		{
//			if (gcd != decimal.One)
//			{
//				this.Numerator = num / gcd;
//				this.Denominator = den / gcd;
//			}
//			else
//			{
//				this.Numerator = num;
//				this.Denominator = den;
//			}
//			if (this.Denominator < 0)
//			{
//				this.Numerator = decimal.Negate(this.Numerator);
//				this.Denominator = decimal.Negate(this.Denominator);
//			}
//		}

//		public static Fraction One { get { return new Fraction(1, 1, decimal.One); } }
//		public static Fraction Zero { get { return new Fraction(0, 1, decimal.One); } }
//		public static Fraction MinusOne { get { return new Fraction(-1, 1, decimal.One); } }
//		public static Fraction NaN { get { return new Fraction(0, 0, decimal.One); } }

//		public static Fraction Add(Fraction a, Fraction b)
//		{
//			decimal lcm = Math.LCM(a.Denominator, b.Denominator);
//			decimal lcmA = lcm / a.Denominator;
//			decimal lcmB = lcm / b.Denominator;
//			return new Fraction(a.Numerator *lcmA + b.Numerator * lcmB, lcm);
//		}

//		public static Fraction Subtract(Fraction a, Fraction b)
//		{
//			decimal lcm = Math.LCM(a.Denominator, b.Denominator);
//			decimal lcmA = lcm / a.Denominator;
//			decimal lcmB = lcm / b.Denominator;
//			return new Fraction(a.Numerator * lcmA - b.Numerator * lcmB, lcm);
//		}

//		public static Fraction Multiply(Fraction a, Fraction b)
//		{
//			decimal gcd1 = Math.GCD(a.Numerator, b.Denominator);
//			decimal gcd2 = Math.GCD(b.Numerator, a.Denominator);
//			return new Fraction((a.Numerator / gcd1) * (b.Numerator / gcd2), (a.Denominator / gcd2) * (b.Denominator / gcd1), decimal.One);
//		}

//		public static Fraction Divide(Fraction a, Fraction b)
//		{
//			decimal gcd1 = Math.GCD(a.Numerator, b.Numerator);
//			decimal gcd2 = Math.GCD(a.Denominator, b.Denominator);
//			return new Fraction((a.Numerator / gcd1) * (b.Denominator / gcd2), (a.Denominator / gcd2) * (b.Numerator / gcd1), decimal.One);
//		}

//		public static bool operator ==(Fraction a, Fraction b)
//		{
//			return (a.Numerator == b.Numerator && a.Denominator == b.Denominator);
//		}

//		public override bool Equals(object obj)
//		{
//			if (!(obj is Fraction))
//				return false;
//			return (this == (Fraction)obj);
//		}

//		public static bool operator !=(Fraction a, Fraction b)
//		{
//			return !(a == b);
//		}

//		public static Fraction operator +(Fraction a, Fraction b)
//		{
//			return Fraction.Add(a, b);
//		}

//		public static Fraction operator -(Fraction a, Fraction b)
//		{
//			return Fraction.Subtract(a, b);
//		}

//		public static Fraction operator *(Fraction a, Fraction b)
//		{
//			return Fraction.Multiply(a, b);
//		}

//		public static Fraction operator /(Fraction a, Fraction b)
//		{
//			return Fraction.Divide(a, b);
//		}

//		public static bool operator <(Fraction a, Fraction b)
//		{
//			return (a.ToDecimal() < b.ToDecimal());
//		}

//		public static bool operator <=(Fraction a, Fraction b)
//		{
//			if (a == b)
//				return true;
//			return (a < b);
//		}

//		public static bool operator >(Fraction a, Fraction b)
//		{
//			return (a.ToDecimal() > b.ToDecimal());
//		}

//		public static bool operator >=(Fraction a, Fraction b)
//		{
//			if (a == b)
//				return true;
//			return (a > b);
//		}

//		public static implicit operator Fraction(Int64 i)
//		{
//			return new Fraction(i, decimal.One, decimal.One);
//		}

//		public static explicit operator Fraction(decimal d)
//		{
//			return new Fraction(d);
//		}

		

//		public static bool TryParse(string text, out Fraction value)
//		{
//			string[] s = text.Split('/');
//			value = Fraction.NaN;
//			if (s.Length > 2)
//				return false;
//			decimal num;
//			if (decimal.TryParse(s[0], out num) == false)
//				return false;
//			decimal den = decimal.One;
//			if (s.Length > 1)
//			{
//				if (decimal.TryParse(s[1], out den) == false)
//					return false;
//			}
//			value = new Fraction(num, den);
//			return true;
//		}

//		public override string ToString()
//		{
//			StringBuilder sb = new StringBuilder();
//			sb.Append(this.Numerator);
//			if (this.Denominator != decimal.One)
//			{
//				sb.Append('/');
//				sb.Append(this.Denominator);
//			}
//			return sb.ToString();
//		}

//		public decimal ToDecimal()
//		{
//			return this.Numerator / this.Denominator;
//		}

//		public double ToDouble()
//		{
//			return decimal.ToDouble(this.Numerator) / decimal.ToDouble(this.Denominator);
//		}

//		#region IScalar
//		string IFormattable.ToString(string format, IFormatProvider formatProvider)
//		{
//			throw new NotImplementedException();
//		}

//		bool IScalar.IsEqualTo(IScalar value) { return this.Equals(value); }
//		IScalar IScalar.Add(IScalar value) { return Fraction.Add(this, (Fraction)value); }
//		IScalar IScalar.Subtract(IScalar value) { return Fraction.Subtract(this, (Fraction)value); }
//		IScalar IScalar.Multiply(IScalar value) { return Fraction.Multiply(this, (Fraction)value); }
//		IScalar IScalar.Divide(IScalar value) { return Fraction.Divide(this, (Fraction)value); }
//		IOperand IOperand.GetDeepCopy() { return new Fraction(this.Numerator, this.Denominator, decimal.One); }

//		bool ILinearScalar.IsGreaterThan(ILinearScalar value)
//		{
//			return (this > (Fraction)value);
//		}

//		bool ILinearScalar.IsSmallerThan(ILinearScalar value)
//		{
//			return (this < (Fraction)value);
//		}

//		int IComparable.CompareTo(object obj)
//		{
//			Fraction f = (Fraction)obj;
//			if (this == f)
//				return 0;
//			if (this < f)
//				return -1;
//			return 1;
//		}
//		#endregion
//	}
//}
